﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using HtmlAgilityPack;
using BLLTZS;
using BLLTZS.Funcionalidad;
using System.Configuration;
using System.IO;

namespace Robador
{
    public partial class FrmRobarBumeran : Form
    {
        public FrmRobarBumeran()
        {
            InitializeComponent();
        }

        #region Robar Ofertas

        private void btnRobar_Click(object sender, EventArgs e)
        {
            btnRobar.Enabled = false;
            bgwRobador.RunWorkerAsync(txtMaximo.Text);
        }

        private string ExtraerCampoTablita(string nombreEtiqueta, bool equal, List<HtmlNode> filas)
        {
            string valor = string.Empty;

            foreach (HtmlNode fila in filas)
            {
                HtmlNode etiqueta = fila.Descendants().Where(n => n.Name == "th").ToList().FirstOrDefault();

                if ( (equal &&  etiqueta.InnerText.TrimEnd().TrimStart().Equals(nombreEtiqueta) )
                    ||( !equal && etiqueta.InnerText.TrimEnd().TrimStart().Contains(nombreEtiqueta)))
                {
                    HtmlNode valorElemento = fila.Descendants().Where(n => n.Name == "td").ToList().FirstOrDefault();
                    valor = ProcesarNombre(valorElemento.InnerText.TrimEnd().TrimStart());
                    break;
                }
            }

            return valor;
        }

        private OfertaReelevada ConvertirOferta(HtmlNode elementoOferta)
        {
            OfertaReelevada oferta = new OfertaReelevada();
            string url = "[PIJA]";

            try
            {
                url = ConfigurationSettings.AppSettings["Bumeran"] + elementoOferta.Attributes["href"].Value.Trim();
                WebClient wc = new WebClient();
                string html = wc.DownloadString(url);
                byte[] bytes = Encoding.Default.GetBytes(html);
                html = Encoding.UTF8.GetString(bytes);

                HtmlAgilityPack.HtmlDocument documento = new HtmlAgilityPack.HtmlDocument();
                documento.LoadHtml(html);

                HtmlNode contenedorOferta = documento.DocumentNode.Descendants().Where(n => n.Name == "div" && n.Attributes["class"] != null && n.Attributes["class"].Value == "span-two-thirds").FirstOrDefault();

                HtmlNode contenedorImagenOferente = contenedorOferta.Descendants().Where(n => n.Name == "div" && n.Attributes["class"] != null && n.Attributes["class"].Value == "aviso-logo-empresa pull-right").FirstOrDefault();
                HtmlNode imagenOferente = contenedorImagenOferente.Descendants().Where(n => n.Name == "img").FirstOrDefault();

                if (imagenOferente != null)
                    oferta.ImagenOferente = imagenOferente.Attributes["src"].Value;

                HtmlNode contenedorTitulo = contenedorOferta.Descendants().Where(n => n.Name == "div" && n.Attributes["class"] != null && n.Attributes["class"].Value == "box").FirstOrDefault();
                HtmlNode hacheDosTitulo = contenedorTitulo.Descendants().Where(n => n.Name == "h2").FirstOrDefault();
                oferta.Titulo = hacheDosTitulo.InnerText.Trim();

                HtmlNode tablaDatos = contenedorOferta.Descendants().Where(n => n.Name == "table" && n.Attributes["class"] != null && n.Attributes["class"].Value == "aviso-resumen-datos").FirstOrDefault();
                List<HtmlNode> filasTablas = tablaDatos.Descendants().Where(n => n.Name == "tr").ToList();

                oferta.FechaPublicacion = ExtraerCampoTablita("Publicado", true, filasTablas);
                oferta.Area = ExtraerCampoTablita("rea", false, filasTablas);
                oferta.TipoPuesto = ExtraerCampoTablita("Tipo de puesto", true, filasTablas);

                HtmlNode divLocalidad = tablaDatos.Descendants().Where(n => n.Name == "div" && n.Attributes["id"] != null && n.Attributes["id"].Value == "modalMapa").FirstOrDefault();
                HtmlNode elementoLocalidad = divLocalidad.Descendants().Where(n => n.Name == "p").FirstOrDefault();
                oferta.Lugar = elementoLocalidad.InnerText.TrimEnd().TrimStart();

                HtmlNode contenidoAviso = contenedorOferta.Descendants().Where(n => n.Name == "div" && n.Attributes["id"] != null && n.Attributes["id"].Value == "contenido_aviso").FirstOrDefault();
                oferta.Descripcion = System.Web.HttpUtility.HtmlDecode(contenidoAviso.InnerHtml);
            }
            catch (Exception ex)
            {
                using (StreamWriter writer = new StreamWriter("RobeiraError.txt", true))
                {
                    writer.WriteLine("-------" + DateTime.Now.ToString() + "------------");
                    writer.WriteLine("URL: " + url);
                    writer.WriteLine();
                    writer.WriteLine(ex.Message);
                    writer.WriteLine();
                    writer.WriteLine(ex.StackTrace);
                    writer.WriteLine("---------------------------------------------------");
                    writer.WriteLine();
                }

                return null;
            }

            return oferta;
        }

        private void bgwRobador_DoWork(object sender, DoWorkEventArgs e)
        {
            decimal total = decimal.Parse(e.Argument.ToString());
            decimal contados = 0;
            decimal porcentaje = 0;
            bool esHoraDePartir = false;
            int pagina = 1;
            List<OfertaReelevada> ofertas = new List<OfertaReelevada>();

            do
            {
                string url;

                if (File.Exists("RobeiraError.txt"))
                    File.Delete("RobeiraError.txt");

                if (pagina == 1)
                    url = ConfigurationSettings.AppSettings["BumeranInicial"];
                else
                    url = string.Format(ConfigurationSettings.AppSettings["BumeranVaginal"], pagina.ToString());

                WebClient wc = new WebClient();
                string html = wc.DownloadString(url);
                HtmlAgilityPack.HtmlDocument documento = new HtmlAgilityPack.HtmlDocument();
                documento.LoadHtml(html);

                HtmlNode contenedorOfertas = documento.DocumentNode.Descendants().Where(x => (x.Name == "div" && x.Attributes["class"] != null &&
                x.Attributes["class"].Value.Contains("span12"))).FirstOrDefault();

                List<HtmlNode> elementosOfertas = contenedorOfertas.ChildNodes.Where(c => c.Name == "a").ToList();

                foreach (HtmlNode item in elementosOfertas)
                {
                    OfertaReelevada oferta = ConvertirOferta(item);
                    if (oferta != null)
                        ofertas.Add(oferta);

                    contados++;
                    porcentaje = contados / total * 100;
                    bgwRobador.ReportProgress((int)porcentaje);

                    if (contados == total)
                    {
                        esHoraDePartir = true;
                        break;
                    }
                }

            } while (!esHoraDePartir);
            e.Result = ofertas;
            OfertaReelevada.Guardar("LoteCache.xml", ofertas);
        }

        private void bgwRobador_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            int porcentaje = (int)e.ProgressPercentage;
            pbEstadoRobar.Value = porcentaje;
            int cantidad = int.Parse(lblCantidadRobados.Text);
            cantidad++;
            lblCantidadRobados.Text = cantidad.ToString();
        }

        private void bgwRobador_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            btnRobar.Enabled = true;

            if (e.Error != null)
            {
                MessageBox.Show(e.Error.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            _ofertas = e.Result as List<OfertaReelevada>;
            ValidarBotonesPaginado();
        }

        #endregion

        #region Localidades

        private void btnRobarLocalidades_Click(object sender, EventArgs e)
        {
            btnRobarLocalidades.Enabled = false;
            pbEstadoRoboLocalidades.Value = 0;
            bgwRobadorLocalidades.RunWorkerAsync();
        }

        private string ProcesarNombre(string nombre)
        {
            if (nombre.Contains("("))
            {
                int indice = nombre.IndexOf("(");
                nombre = nombre.Substring(0, indice);
            }
            nombre = nombre.TrimStart().TrimEnd();

            return nombre;
        }

        private void bgwRobadorLocalidades_DoWork(object sender, DoWorkEventArgs e)
        {
            double total = 0;
            double contados = 0;
            double porcentaje = 0;
            WebClient wc = new WebClient();
            string html = wc.DownloadString(System.Configuration.ConfigurationSettings.AppSettings["UrlLocalidades"]);

            HtmlAgilityPack.HtmlDocument documento = new HtmlAgilityPack.HtmlDocument();
            documento.LoadHtml(html);

            HtmlNode divPadre = documento.DocumentNode.Descendants().Where(n => n.Name == "div" && n.Attributes["lang"] != null && n.Attributes["lang"].Value.Trim() == "es"
                                && n.Attributes["dir"] != null && n.Attributes["dir"].Value == "ltr"
                                && n.Attributes["class"] != null && n.Attributes["class"].Value.Contains("mw-content-ltr")).FirstOrDefault();

            List<HtmlNode> tablas = divPadre.Descendants().Where(n => n.Name == "table" && n.Attributes["style"] != null & n.Attributes["style"].Value.Contains("width: 100%")).ToList();

            foreach (HtmlNode tabla in tablas)
            {
                List<HtmlNode> elementosLocalidad = tabla.Descendants().Where(n => n.Name == "a" && n.Attributes["title"] != null).ToList();

                if (elementosLocalidad.Count == 0)
                    continue;

                total = elementosLocalidad.Count;

                foreach (HtmlNode item in elementosLocalidad)
                {
                    string nombreLocalidad = ProcesarNombre(item.Attributes["title"].Value);
                    byte[] bytes = Encoding.Default.GetBytes(nombreLocalidad);
                    nombreLocalidad = Encoding.UTF8.GetString(bytes);

                    BLLLocalidad bll = new BLLLocalidad();

                    if (!bll.Existe(nombreLocalidad))
                    {
                        bll.CargarLocalidad(new TZS_Localidad() { Nombre = nombreLocalidad });
                        bll.GuardarCambios();
                    }
                    
                    contados++;
                    porcentaje = contados / total * 100;
                    bgwRobadorLocalidades.ReportProgress((int)porcentaje);
                }
            }
        }

        private void bgwRobadorLocalidades_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            int porcentaje = (int) e.ProgressPercentage;
            pbEstadoRoboLocalidades.Value = porcentaje;
        }

        private void bgwRobadorLocalidades_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            btnRobarLocalidades.Enabled = true;
        }

        #endregion

        #region Navergar Ofertas

        private List<OfertaReelevada> _ofertas;

        private void CargarOfertas()
        {
            int pagina = int.Parse(txtPagina.Text);
            int cantidad = int.Parse(txtCantidad.Text);
            int skip = (pagina == 1) ? 0 : cantidad * (pagina - 1);

            var query = (from o in _ofertas
                         select new
                         {
                             Titulo = o.Titulo,
                             Fecha = o.FechaPublicacion
                         });

            dgvOfertasRobadas.DataSource = query.Skip(skip).Take(cantidad).ToList();

            ValidarBotonesPaginado();
        }

        private void ValidarBotonesPaginado()
        {
            btnAnterior.Enabled = btnSiguiente.Enabled = false;
            int pagina = int.Parse(txtPagina.Text);

            btnAnterior.Enabled = pagina > 1;

            int cantidad = int.Parse(txtCantidad.Text);
            int totalPagina = _ofertas.Count / cantidad;
            btnSiguiente.Enabled = pagina < totalPagina;
        }

        private void btnSiguiente_Click(object sender, EventArgs e)
        {
            int pagina = int.Parse(txtPagina.Text);
            txtPagina.Text = (pagina + 1).ToString();
            CargarOfertas();
        }

        private void btnAnterior_Click(object sender, EventArgs e)
        {
            int pagina = int.Parse(txtPagina.Text);
            txtPagina.Text = (pagina - 1).ToString();
            CargarOfertas();
        }

        private void btnTraerCache_Click(object sender, EventArgs e)
        {
            _ofertas = OfertaReelevada.Abrir("LoteCache.xml");
            txtPagina.Text = "1";
            CargarOfertas();
        }

        #endregion
    }
}
